﻿// HisChromG.cpp: 实现文件
//

#include "stdafx.h"
#include "DC-QC.h"
#include "HisChromG.h"


// CHisChromG

IMPLEMENT_DYNAMIC(CHisChromG, CWnd)

CHisChromG::CHisChromG()
{
	m_nMaxYA = 10;
	m_nMaxYB = 10;
	m_nXScale = 30;		//30 add by zhupj
	m_nMinYA = 0;
	m_nMinYB = 0;
	m_nLineWidth = 2;
}

CHisChromG::~CHisChromG()
{
}


BEGIN_MESSAGE_MAP(CHisChromG, CWnd)
	ON_WM_PAINT()
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONUP()
	ON_WM_MOUSEMOVE()
	ON_WM_CREATE()
END_MESSAGE_MAP()



// CHisChromG 消息处理程序
void CHisChromG::OnPaint()
{
	CPaintDC dc(this); // device context for painting
					   // TODO: 在此处添加消息处理程序代码
					   // 不为绘图消息调用 CWnd::OnPaint()
	CRect rect;
	GetClientRect(&rect);

	CBitmap ClientScreen, *pOldBitmap;
	CRect UpdateRect(rect);

	CDC MDC;
	MDC.CreateCompatibleDC(&dc);
	ClientScreen.CreateCompatibleBitmap(&dc, rect.Width(), rect.Height());
	pOldBitmap = MDC.SelectObject(&ClientScreen);
	MDC.FillSolidRect(UpdateRect, RGB(255, 255, 255));

	Draw(&MDC, rect);

	dc.BitBlt(UpdateRect.left, UpdateRect.top,
		UpdateRect.right - UpdateRect.left,
		UpdateRect.bottom - UpdateRect.top,
		&MDC, UpdateRect.left, UpdateRect.top, SRCCOPY);
	MDC.SelectObject(pOldBitmap);

	ClientScreen.DeleteObject();
	MDC.DeleteDC();
}


void CHisChromG::Draw(CDC* pDC, CRect rt)
{
	try
	{
		DrawInBorder(pDC, rt);
		rt.DeflateRect(1, 1, 1, 1);
		BxGradientFill(pDC, rt, BACKCOLOR1, BACKCOLOR2, 1);
		rt.DeflateRect(60*g_DPIScaleX, 10*g_DPIScaleY, 10*g_DPIScaleX, 20*g_DPIScaleY);
		CFont* pF = pDC->SelectObject(&gl.m_pSmallFont);
		DrawFrame(rt, pDC);
		DrawCurve(rt, pDC);
		m_rcArea = rt;
		pDC->SelectObject(pF);
	}
	catch (...)
	{
	}
}

void CHisChromG::DrawFrame(CRect rt, CDC *pDC)
{
	int	m_left = rt.left;
	int	m_top = rt.top;
	int	m_right = rt.right;
	int	m_bottom = rt.bottom;
	//创建画笔对象
	CPen pPenBlack(PS_SOLID, 2, RGB(255, 255, 255));
	CPen pPenG(PS_DOT, 1, RGB(5, 85, 5));
	CFont* pF = (CFont*)pDC->SelectObject(&font); //保存当前字体
	pDC->SetBkMode(TRANSPARENT);

	pDC->SetTextColor(RGB(255, 128, 0));
	//绘制A窗口线
	int nLastP = 0;
	CPoint pt;
	int nWidth = rt.Width();
	int nHeight = rt.Height();
	int nOldDrawMode = pDC->SetROP2(R2_XORPEN);
	int CIndex, LIndex, RIndex;
	for (int jj = 0; jj < 7; jj++)
	{
		CIndex = gl.gcCi.scA[jj].RealyTime*DATAFREQUENCE;
		if (nLastP == 0)
			LIndex = CIndex - gl.gcCi.scA[jj].Wrap*DATAFREQUENCE / 2;
		else
		{
			if (CIndex - gl.gcCi.scA[jj].Wrap*DATAFREQUENCE / 2 < nLastP)
				LIndex = nLastP;
			else
				LIndex = CIndex - gl.gcCi.scA[jj].Wrap*DATAFREQUENCE / 2;
		}
		RIndex = CIndex + gl.gcCi.scA[jj].Wrap*DATAFREQUENCE / 2;
		if (RIndex >= gl.MAXPOINTS) RIndex = gl.MAXPOINTS - 1;
		nLastP = RIndex;

		pt.x = rt.left + LIndex * nWidth / gl.MAXPOINTS;
		pt.y = rt.bottom - 2*g_DPIScaleY;
		int nAWidth = (RIndex - LIndex) * nWidth / gl.MAXPOINTS;
		int nAHeight = nHeight - 4*g_DPIScaleY;
		CRect rtChromA = CRect(pt, CSize(nAWidth, (-1)*nAHeight));


		//int oldBkMode = pDC->SetBkMode(OPAQUE); 
		//pDC->FillSolidRect(rtChromA, RGB(0, 200, 0)); 
		//CBrush fillBrush(RGB(0, 200, 0));
		//pDC->SelectObject(&fillBrush);   
		//pDC->Rectangle(rtChromA);        
		//pDC->SetBkMode(oldBkMode);


		CString strTemp;
		//strTemp.Format(_T("%s=%.2f"),gl.curChromA.ChS[jj].Name, CIndex*30.0/gl.MAXPOINTS); 
		strTemp.Format(_T("%s"), gl.gcCi.scA[jj].strName);
		pt.x = rt.left + CIndex * nWidth / gl.MAXPOINTS;
		pDC->TextOut(pt.x, pt.y - 14*g_DPIScaleY, strTemp);
	}
	pDC->SetROP2(nOldDrawMode);

	CPen* pOldPen = pDC->SelectObject(&pPenBlack);
	pDC->SetTextColor(RGB(255, 255, 255));

	// 绘制X轴刻度
	int nTemp;
	CString strTemp;
	CRect rect1(0, 0, 0, 0);

	// 创建字体对象
	CFont font;
	font.CreateFont(
		20,                        // 字体高度（单位为逻辑单元）
		0,                         // 字符的平均宽度
		0,                         // 文本的倾斜角度
		0,                         // 基线的倾斜角度
		FW_MEDIUM,                 // 字体粗细
		FALSE,                     // 是否斜体
		FALSE,                     // 是否下划线
		0,                         // 是否删除线
		ANSI_CHARSET,              // 字符集
		OUT_DEFAULT_PRECIS,        // 输出精度
		CLIP_DEFAULT_PRECIS,       // 裁剪精度
		DEFAULT_QUALITY,           // 输出质量
		DEFAULT_PITCH | FF_SWISS,  // 字体族和间距
		_T("Arial"));              // 字体名称

	// 保存原字体
	CFont* pOldFont = pDC->SelectObject(&font);

	COLORREF textColor = RGB(0, 0, 0); // 设置字体颜色为蓝色
	int oldBkMode = pDC->SetTextColor(textColor); // 设置字体颜色

	for (int i = 0; i <= gl.gcMachine.nXScale; i++)
	{
		nTemp = (m_right - m_left)*i / gl.gcMachine.nXScale + m_left;
		strTemp.Format(_T("%d"), i);
		pDC->MoveTo(nTemp, m_bottom);
		if (i % 5 == 0)
		{
			pDC->SelectObject(&pPenG);
			pDC->LineTo(nTemp, m_top);
			pDC->SelectObject(&pPenBlack);
		}
		else
			pDC->LineTo(nTemp, m_bottom - 4);

		pDC->SelectObject(pPenBlack);
		if (i % 5 == 0)
			pDC->ExtTextOut(nTemp - 6*g_DPIScaleX, m_bottom + 2*g_DPIScaleY, ETO_OPAQUE, rect1, strTemp, NULL);
	}
	pDC->SetBkMode(oldBkMode);

	// 恢复原字体
	pDC->SelectObject(pOldFont);

	// 删除字体对象
	font.DeleteObject();

	CPen  pPenY1(PS_SOLID, 2, gl.gcMachine.nLineColor[0]);
	pDC->SelectObject(&pPenY1);
	if(m_nCHX==0)
	{
		pDC->SetTextColor(gl.gcMachine.nLineColor[0]);
		pDC->DrawText(_T("通道--A"),rt,DT_CENTER | DT_TOP | DT_SINGLELINE);
	}
	else
	{
		pDC->SetTextColor(gl.gcMachine.nLineColor[1]);
		pDC->DrawText(_T("通道--B"),rt,DT_CENTER | DT_TOP | DT_SINGLELINE);
	}


	// 绘制A Y轴网格
	pDC->MoveTo(rt.TopLeft());
	pDC->LineTo(m_left, m_bottom);
	pDC->LineTo(rt.BottomRight());
	for (int i = 1; i <= 10; i++)
	{
		nTemp = -(m_bottom - m_top)*i / 10 + m_bottom;
		strTemp.Format(_T("%.0f"), m_nMinYA + (m_nMaxYA - m_nMinYA)*i / 10.0);
		pDC->SelectObject(&pPenG);
		pDC->MoveTo(m_left, nTemp);
		pDC->LineTo(m_right, nTemp);
		pDC->SelectObject(&pPenBlack);
		if (i == 0) continue;
		int nL = strTemp.GetLength();
		pDC->ExtTextOut(m_left - 12 * nL*g_DPIScaleX, nTemp - 6*g_DPIScaleY, ETO_OPAQUE, rect1, strTemp, NULL);
		if (i == 10) 		pDC->ExtTextOut(m_left + 12*g_DPIScaleX, nTemp+4*g_DPIScaleY, ETO_OPAQUE, rect1, _T("组份(mV)"), NULL);
	}
	// 绘制B Y轴网格
	CPen pPenY2(PS_SOLID, 2, gl.gcMachine.nLineColor[2]);
	pDC->SelectObject(&pPenY2);
	pDC->SetTextColor(gl.gcMachine.nLineColor[2]);
	pDC->MoveTo(rt.right, rt.top);
	pDC->LineTo(rt.BottomRight());
	m_left = rt.right;
	for (int i = 0; i <= 10; i++)
	{
		nTemp = -(m_bottom - m_top)*i / 10 + m_bottom;
		strTemp.Format(_T("%.0f"), m_nMinYB + (m_nMaxYB - m_nMinYB)*i / 10.0);
		pDC->MoveTo(m_left, nTemp);
		pDC->LineTo(m_left - 8, nTemp);
		if (i == 0) continue;
		int nL = strTemp.GetLength();
		pDC->ExtTextOut(m_left - 12 * nL*g_DPIScaleX, nTemp - 6*g_DPIScaleY, ETO_OPAQUE, rect1, strTemp, NULL);
		if (i == 10) pDC->ExtTextOut(m_left - 62*g_DPIScaleX, nTemp + 4, ETO_OPAQUE, rect1, _T("全烃(mV)"), NULL);
	}
	pDC->SelectObject(pOldPen);
	pDC->SelectObject(pF);		//恢复以前的字体
}

void CHisChromG::DrawCurve(CRect rt, CDC *pDC)
{
	CFont   font;
	CFont   *pOldFont;
	font.CreateFont(12, 0, 2700, 2700, FW_NORMAL,
		0, 0, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
		CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
		DEFAULT_PITCH, _T("@宋体"));
	pOldFont = pDC->SelectObject(&font);

	CPoint pt;
	CPen* pOldPen = NULL;

	int nWidth = rt.Width();
	int nHeight = rt.Height();
	double nMaxAY = m_nMaxYA;
	double nMaxBY = m_nMaxYB;
	double nMinY = 0;

	CPen pPenA1(PS_SOLID, m_nLineWidth, gl.gcMachine.nLineColor[0]);
	CPen pPenA2(PS_SOLID, m_nLineWidth, gl.gcMachine.nLineColor[1]);
	CPen pPenB(PS_SOLID, m_nLineWidth, gl.gcMachine.nLineColor[2]);

	for (int nCh = 0; nCh < 2; nCh++)
	{
		if (nCh == 0)
		{
			nMinY = m_nMinYA;			
			if (m_nCHX == 0)
			{
				pOldPen = pDC->SelectObject(&pPenA1);
				pDC->SetTextColor(gl.gcMachine.nLineColor[0]);
			}
			else
			{
				pOldPen = pDC->SelectObject(&pPenA2);
				pDC->SetTextColor(gl.gcMachine.nLineColor[1]);
			}
		}
		else
		{
			nMinY = m_nMinYB;
			pOldPen = pDC->SelectObject(&pPenB);
			pDC->SetTextColor(gl.gcMachine.nLineColor[2]);
		}

		for (int i = 0; i < gl.MAXPOINTS; i++)
		{
			if (curChrom.CA[i] == -999) break;
			pt.x = rt.left + i * nWidth / gl.MAXPOINTS;
			if (nCh == 0)
				pt.y = rt.bottom - (curChrom.CA[i] - nMinY)*nHeight*1.0 / (nMaxAY - nMinY);
			else
				pt.y = rt.bottom - (curChrom.CB[i] - nMinY)*nHeight*1.0 / (nMaxBY - nMinY);

			if (pt.y < rt.top) pt.y = rt.top;
			if (pt.y > rt.bottom) pt.y = rt.bottom;
			if (i == 0)
				pDC->MoveTo(pt);
			else
				pDC->LineTo(pt);
		}
	}
	//绘制时间标
	pt.x = rt.left + curChrom.CAIndex*nWidth / gl.MAXPOINTS;
	pt.y = rt.bottom - 10;
	pDC->MoveTo(pt);
	pt.y = rt.bottom + 10;
	pDC->LineTo(pt);

	pDC->SelectObject(pOldFont);
	pDC->SelectObject(pOldPen);
}

void CHisChromG::FindMinMax()
{
	double maxA = -999;
	double maxB = -999;
	double min = 999999;
	for (int i = 0; i < curChrom.CAIndex; i++)
	{
		if (maxA < curChrom.CA[i]) maxA = curChrom.CA[i];
		if (maxB < curChrom.CB[i]) maxB = curChrom.CB[i];
		if (min > curChrom.CA[i]) min = curChrom.CA[i];
		if (min > curChrom.CB[i]) min = curChrom.CB[i];
	}
	int nStep = 2;
	if (maxA > 20000) nStep = 10000;
	else if (maxA > 2000) nStep = 1000;
	else if (maxA > 100) nStep = 100;
	else if (maxA > 20) nStep = 10;
	else if (maxA > 10) nStep = 5;

	m_nMaxYA = int(maxA / nStep + 1)*nStep;
	if (m_nMaxYA < 10) m_nMaxYA = 10;
	m_nMinYA = 0;

	nStep = 2;
	if (maxB > 20000) nStep = 10000;
	else if (maxB > 2000) nStep = 1000;
	else if (maxB > 100) nStep = 100;
	else if (maxB > 20) nStep = 10;
	else if (maxB > 10) nStep = 5;
	m_nMaxYB = int(maxB / nStep + 1)*nStep;
	if (m_nMaxYB < 10) m_nMaxYB = 10;
	m_nMinYB = 0;
}


void CHisChromG::OnLButtonDown(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	m_bMouseDown = TRUE;
	SetCapture();			// 启动鼠标捕捉
	c_ptDown = point;

	CWnd::OnLButtonDown(nFlags, point);
}


void CHisChromG::OnLButtonUp(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	m_bMouseDown = FALSE;
	ReleaseCapture();				// 释放鼠标捕捉
	c_ptLast = point;

	if (m_nZoomMode == 1)			//缩放的处理
	{
		CaculateZoom(c_ptDown, c_ptLast);
	}

	Invalidate();
	CWnd::OnLButtonUp(nFlags, point);
}

void CHisChromG::OnMouseMove(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	if (m_nZoomMode == 1 && m_bMouseDown)
	{
		CClientDC dc(this);
		DrawDynamicRect(&dc, c_ptDown, c_ptLast, point);
	}
	else
	{
		CClientDC dc(this);
		RelayEvent(WM_MOUSEMOVE, (WPARAM)nFlags, MAKELPARAM(LOWORD(point.x), LOWORD(point.y)));
		//信息提示
		dc.DPtoLP(&point);
		CString strTemp = GetTips(point);
		if (m_strTipsString != strTemp && strTemp.GetLength()!=0)
		{
			m_strTipsString = strTemp;
			m_Tips.UpdateTipText(strTemp, this);
		}
	}
	c_ptLast = point;
	CWnd::OnMouseMove(nFlags, point);
}

////////////////////////////////////////////////////////////////////////////////////////////////
//缩放操作
void CHisChromG::DrawDynamicRect(CDC *pDC, CPoint ptBegin, CPoint ptOld, CPoint ptNew)
{
	int nOldDrawMode;
	//设置光栅操作模式:
	nOldDrawMode = pDC->SetROP2(R2_XORPEN);

	CPen	curPen, *pOldPen;
	if (!curPen.CreatePen(PS_SOLID, 1, RGB(0, 255, 0)))
		return;
	pOldPen = (CPen*)pDC->SelectObject(&curPen);
	//坐标转换
	pDC->DPtoLP(&ptBegin);
	pDC->DPtoLP(&ptOld);
	pDC->DPtoLP(&ptNew);

	//消隐旧虚线
	if (ptBegin.x < ptOld.x)
	{
		//绘制这样的"]"矩形			*这一段代码可以不使用分枝.
		pDC->MoveTo(ptBegin);
		pDC->LineTo(ptOld.x, ptBegin.y);
		pDC->LineTo(ptOld);
		pDC->LineTo(ptBegin.x, ptOld.y);
		pDC->LineTo(ptBegin);
	}
	else
	{
		//绘制这样的"["矩形
		pDC->MoveTo(ptBegin);
		pDC->LineTo(ptOld.x, ptBegin.y);
		pDC->LineTo(ptOld);
		pDC->LineTo(ptBegin.x, ptOld.y);
		pDC->LineTo(ptBegin);
	}

	//画新虚线
	if (ptBegin.x < ptNew.x)
	{
		//绘制这样的"]"矩形			*这一段代码可以不使用分枝.
		pDC->MoveTo(ptBegin);
		pDC->LineTo(ptNew.x, ptBegin.y);
		pDC->LineTo(ptNew);
		pDC->LineTo(ptBegin.x, ptNew.y);
		pDC->LineTo(ptBegin);
	}
	else
	{
		//绘制这样的"["矩形
		pDC->MoveTo(ptBegin);
		pDC->LineTo(ptNew.x, ptBegin.y);
		pDC->LineTo(ptNew);
		pDC->LineTo(ptBegin.x, ptNew.y);
		pDC->LineTo(ptBegin);
	}

	pDC->SelectObject(pOldPen);
	pDC->SetROP2(nOldDrawMode);
}


void CHisChromG::CaculateZoom(CPoint ptBegin, CPoint ptEnd)
{
	if (ptBegin.y > ptEnd.y)	//还原
	{
		m_nMaxYA = gl.gcMachine.nYMax[0];
		m_nMaxYB = gl.gcMachine.nYMax[1];
		m_nMinYA = gl.gcMachine.nYMin[0];
		m_nMinYB = gl.gcMachine.nYMin[1];
		m_nZoomMode = 1;
		Invalidate();
	}
	else
	{
		long nMaxYA = GetPointY(ptBegin, 0);		//坐标轴的刻度设置
		long nMaxYB = GetPointY(ptBegin, 1);
		long nMinYA = GetPointY(ptEnd, 0);
		long nMinYB = GetPointY(ptEnd, 1);
		if (nMaxYA > nMinYA)		//缩放
		{
			m_nMaxYA = nMaxYA;
			m_nMinYA = nMinYA;
			m_nMaxYB = nMaxYB;
			m_nMinYB = nMinYB;
			Invalidate();
		}
	}
}

////////////////////////////////////////////////////////////////
//		用于MOUSE提示信息
//
//	编写: 朱平军    2008.12.12
//	修改:  ***		日期
//					修改原因和内容
//
//////////////////////////////////////////////////////////////////
void CHisChromG::RelayEvent(UINT message, WPARAM wParam, LPARAM lParam)
{
	if (NULL != m_Tips.m_hWnd)
	{
		MSG msg;

		msg.hwnd = m_hWnd;
		msg.message = message;
		msg.wParam = wParam;
		msg.lParam = lParam;
		msg.time = 1000;
		msg.pt.x = LOWORD(lParam);
		msg.pt.y = HIWORD(lParam);

		m_Tips.RelayEvent(&msg);
	}
}

//得到MOUSE所指的时间
CString CHisChromG::GetTips(CPoint pt)
{
	CString strTemp = _T("");
	try
	{
		int index = GetPointTime(pt)*DATAFREQUENCE;;
		if (index < 0) index = 0;
		if (index >= gl.MAXPOINTS) index = gl.MAXPOINTS - 2;
		float tt = GetPointTime(pt);
		if(curChrom.CA[index]>0)
			strTemp.Format(_T("时间:%5.1fs;\r\n组份=%.4fmv;\r\n全烃=%.4fmv;"), tt,  curChrom.CA[index], curChrom.CB[index]);
		else
			strTemp.Format(_T("时间:%5.1fs;"), tt);
	}
	catch (...)
	{
	}
	return strTemp;
}

float	CHisChromG::GetPointY(CPoint pt, int nYIndex)
{
	float dY = 0;
	if (nYIndex == 0)
		dY = m_nMinYA + (m_nMaxYA - m_nMinYA)*(-pt.y + m_rcArea.bottom) / m_rcArea.Height();
	else
		dY = m_nMinYB + (m_nMaxYB - m_nMinYB)*(-pt.y + m_rcArea.bottom) / m_rcArea.Height();
	return dY;
}

float	CHisChromG::GetPointTime(CPoint pt)
{
	if (m_rcArea.Width() == 0) return 0;
	float dT =  m_nXScale *1.0* (pt.x - m_rcArea.left) / m_rcArea.Width();
	return dT;
}

void	CHisChromG::UpdateGraph(Chrom_File curFile, int nCHX)
{
	curChrom = curFile;
	m_nCHX = nCHX;
	if(gl.gcMachine.nYAuto==1)
		FindMinMax();
	else
	{
		m_nMaxYA = gl.gcMachine.nYMax[0];
		m_nMaxYB = gl.gcMachine.nYMax[1];
	}
	CRect rt;
	GetClientRect(rt);
	InvalidateRect(rt);
}

void	CHisChromG::SetLineWidth(int nWidth)
{
	CRect rt;
	GetClientRect(rt);
	m_nLineWidth = nWidth;

	InvalidateRect(rt);
}

int CHisChromG::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CWnd::OnCreate(lpCreateStruct) == -1)
		return -1;

	// TODO:  在此添加您专用的创建代码
	if (!m_Tips.Create(this))
		TRACE0("Unable to create tip window.");
	else
		if (!m_Tips.AddTool(this, LPCTSTR("")))
			TRACE0("Unable to add tip for the control window.");
		else
		{
			m_Tips.Activate(TRUE);
			m_Tips.SetMaxTipWidth(200);
		}
	return 0;
}
